package builders;

import backbone.IBuildable;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Scanner;
import main.Simulation;


/**
 * Parses input text file and creates new objects in simulation.
 * 
 * @author Paul
 * @author Lance
 * 
 */
public class Factory {
    /**
     * @param sim Simulation object related
     * @param modelFile xsp file formatted as defined by project
     */

    private Map<String, IBuildable> myBuilders;

    /**
     * Builds a factory object.
     */
    public Factory() {
        myBuilders = new HashMap<String, IBuildable>();
        PointObjectBuilder pointBuilder = new PointObjectBuilder();
        LineObjectBuilder lineBuilder = new LineObjectBuilder(pointBuilder);

        myBuilders.put("mass", pointBuilder);
        myBuilders.put("muscle", lineBuilder);
        myBuilders.put("spring", lineBuilder);
        myBuilders.put("gravity", new GravityBuilder());
        myBuilders.put("viscosity", new ViscosityBuilder());
        myBuilders.put("centermass", new CenterMassBuilder());
        myBuilders.put("wall", new WallBuilder());
        myBuilders.put("mousemass", new MouseMassBuilder());
        myBuilders.put("tempspring", new TemporarySpringBuilder(pointBuilder));
    }

    /**
     * Given a specified file, loads the forces/entities
     * it lists.
     * 
     * @param file
     * @param sim
     */
    public void load(File file, Simulation sim) {
        try {
            Scanner input = new Scanner(file);
            while (input.hasNext()) {
                Scanner line = new Scanner(input.nextLine());
                if (line.hasNext()) {
                    String type = line.next();
                    // System.out.println(type);
                    LinkedList<Double> myProperties = new LinkedList<Double>();
                    while (line.hasNextDouble()) {
                        double test = line.nextDouble();
                        // System.out.println(test);
                        myProperties.add(test);
                    }
                    myBuilders.get(type).build(sim, myProperties);
                }
            }
            input.close();
        } 
        catch (FileNotFoundException e) {
            // should not happen because File came from user selection
            e.printStackTrace();
        }
    }

    /**
     * Builds a particular object based on a string
     * specifier. Loads the object to a particular simulation.
     * 
     * @param string
     * @param sim
     * @param properties A list of the properties needed to 
     * create the required object. 
     */
    public void createBuildable(String string, Simulation sim,
            LinkedList<Double> properties) {
        IBuildable buildable = myBuilders.get(string);
        buildable.build(sim, properties);
    }
}
